package com.grao.waterschool.human.manager.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.grao.waterschool.human.common.BusinessException;
import com.grao.waterschool.human.entiry.vo.CapturePicList;
import com.grao.waterschool.human.entiry.vo.HistoryPicList;
import com.grao.waterschool.human.entiry.vo.PageInfo;
import com.grao.waterschool.human.manager.service.CapturePicService;
import com.grao.waterschool.human.manager.service.ICCAuthorizeService;
import com.grao.waterschool.human.mapper.CourseDeviceInfoMapper;
import com.grao.waterschool.human.utils.MinioUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;

import static com.grao.waterschool.human.manager.service.impl.ICCAuthorizeServiceImpl.redisTemplate;
import static com.grao.waterschool.human.manager.service.impl.ICCAuthorizeServiceImpl.refreshToken;
import static com.grao.waterschool.human.manager.service.impl.ICCDeviceServiceImpl.getHeaders;

@EnableScheduling
@Service
@Slf4j
public class CapturePicServiceImpl implements CapturePicService {

    @Autowired
    MinioUtil minioUtil;

//    @Value("${minio.ICCImages}")
    static String bucketName = "iccimages";

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private ICCAuthorizeService iccAuthorizeService;

    String BaseURL = "http://10.0.25.224/evo-apigw/evo-oss";

    @Autowired
    private CourseDeviceInfoMapper courseDeviceInfoMapper;

    @Autowired
    private RestTemplate restTemplate;

    private final String CapturePicURL = "https://10.0.25.224/evo-apigw/admin/API/capture/saveCapturePicPlan";

    private final String getHistoryCapturePic = "https://10.0.25.224/evo-apigw/admin/API/capture/getHistoryCapturePic";


    /**
     * 设置抓图策略
     */
    @Override
    public List<String> capturePic(Integer userId, CapturePicList capturePicList) throws Exception {
        String newToken = refreshToken(userId);
        List<String> allChannelCodes = courseDeviceInfoMapper.selectChannelCodes();

        if (allChannelCodes == null || allChannelCodes.isEmpty()) {
            throw new IllegalStateException("通道为空");
        }
        // 去重处理
        Set<String> uniqueChannelCodesSet = new HashSet<>(allChannelCodes);
        List<String> uniqueChannelCodes = new ArrayList<>(uniqueChannelCodesSet);

        log.info("通道数量：{}", uniqueChannelCodes.size());
        //控制每组数据位10个
        int batchSize = 10;
        int totalSize = uniqueChannelCodes.size();
        int numberOfBatches = (int) Math.ceil((double) totalSize / batchSize);

        List<String> responses = new ArrayList<>();

        for (int i = 0; i < numberOfBatches; i++) {
            int fromIndex = i * batchSize;
            int toIndex = Math.min(fromIndex + batchSize, totalSize);
            List<String> batchChannelIds = allChannelCodes.subList(fromIndex, toIndex);

            // 构建CapturePicList对象
            CapturePicList batchCapturePicList = new CapturePicList();
            batchCapturePicList.setChannelIds(batchChannelIds);
            batchCapturePicList.setPlanName("body" + i);
            batchCapturePicList.setTimeCell(3600);
            batchCapturePicList.setPicQuality(6);
            batchCapturePicList.setMemo("body" + i);
            batchCapturePicList.setTimeTempId(5);
            batchCapturePicList.setDeviceCodes(new ArrayList<>());
            batchCapturePicList.setOrgCodes(new ArrayList<>());
            batchCapturePicList.setPresetPoints(new ArrayList<>());


            log.info("开始构建请求！！！{}", batchCapturePicList);

            log.info("获取到新token！！！{}", newToken);

            // 发送请求
            String response = setCapturePicPlan(newToken, batchCapturePicList);
            responses.add(response);
        }
        return responses;
    }

    /**
     * 发送抓图策略请求
     */
    public String setCapturePicPlan(String newToken, CapturePicList capturePicList) throws JsonProcessingException {
        Map<String, Object> data = new HashMap<>();
        data.put("data", capturePicList);
        data.put("method", "capture.saveCapturePicPlan");
        String jsonRequestBody = objectMapper.writeValueAsString(data);
        log.info("请求参数：{}", jsonRequestBody);
        HttpEntity<String> requestEntity = new HttpEntity<>(jsonRequestBody, getHeaders(newToken));
        ResponseEntity<String> responseEntity = restTemplate.exchange(CapturePicURL, HttpMethod.POST, requestEntity, String.class);
        log.info("发送请求了！！！");
        return responseEntity.getBody();
    }

    /**
     * 查询历史抓图
     */
    @Scheduled(cron = "* 00 18 * * *") // 每天晚上6点执行
    @Override
    public void getHistoryPic() throws Exception {
        log.info("=======开始查询历史抓图！！！=======");
        HistoryPicList historyPicList = new HistoryPicList();
        String newToken = refreshToken(18012);
        List<String> allChannelCodes = courseDeviceInfoMapper.selectChannelCodes();
        long startData = getTimestampAtTime(8, 15);
        long endData = getTimestampAtTime(17, 46);
        historyPicList.setStartDate(startData);
        historyPicList.setEndDate(endData);
        historyPicList.setOrder(0);
        historyPicList.setChannelId(allChannelCodes);

        // 初始化分页参数
        int pageSize = 100;  // 每页大小，根据实际情况设置
        int pageNo = 1;
        List<String> allResults = new ArrayList<>();

        List<String> allCaptureNames = new ArrayList<>();
        while (true) {
            historyPicList.setPageInfo(new PageInfo(pageSize, pageNo));
            log.info("开始构建请求：{}", historyPicList);

            Map<String, Object> data = new HashMap<>();
            data.put("data", historyPicList);

            String jsonRequestBody = objectMapper.writeValueAsString(data);
            log.info("这里是请求参数：{}", jsonRequestBody);

            HttpEntity<String> requestEntity = new HttpEntity<>(jsonRequestBody, getHeaders(newToken));
            ResponseEntity<String> responseEntity = restTemplate.exchange(getHistoryCapturePic, HttpMethod.POST, requestEntity, String.class);
            log.info("返回值：{}", responseEntity.getBody());

            JsonNode rootNode = objectMapper.readTree(responseEntity.getBody());
            if (rootNode.get("code").asInt() != 1000) {
                throw new BusinessException("调用出错啦！！！plz try again");
            } else {
                // 开始解析
                JsonNode datasNode = rootNode.get("data").get("datas");
                if (datasNode.isArray()) {
                    List<String> result = new ArrayList<>();
                    for (JsonNode node : datasNode) {
                        String capturePictureFront = node.get("capturePictureFront").asText();
                        String capturePictureChannelName = node.get("channelName").asText();
                        String capturePictureTime = node.get("captureDate").asText();

                        //这里将时间戳转换为日期和时间，要存入redis，以便后续和课程做匹配
                        convertTimestampToZone(Long.parseLong(capturePictureTime), "Asia/Shanghai", "yyyyMMddHHmmss");

                        long timestamp = Long.parseLong(capturePictureTime); // 假设时间戳是数字字符串

                        // 调用convertTimestampToZone方法
                        String formattedTime = convertTimestampToZone(timestamp, "Asia/Shanghai", "yyyy-MM-dd HH:mm:ss");

                        log.info("转换后的时间: {}", formattedTime);

                        //把时间转换为日期作为文件路径上传
                        String date = extractDate(formattedTime);

                        //构建完整地址
                        //上传到minio上，名字就用capturePictureChannelName + capturePictureTime
                        String URL = BaseURL + capturePictureFront + "?token=" + newToken;
                        String captureName = date + "/" + capturePictureChannelName + "$" + formattedTime;

                        allCaptureNames.add(captureName);
                        minioUtil.uploadToMinio(URL, bucketName, captureName);
                        log.info("已上传的请求：{}", captureName);

                        result.add(URL);
                    }

                    allResults.addAll(result);

                    // 判断是否还有更多数据
                    if (datasNode.size() < pageSize) {
                        break;  // 如果当前页数据小于pageSize，说明已经到最后一页了
                    } else {
                        pageNo++;  // 否则，继续获取下一页
                    }
                } else {
                    throw new BusinessException("返回值不是数组！！！");
                }
            }
        }
        try {
            redisTemplate.opsForList().trim("captureName", 0, -1);
        } catch (Exception e) {
            log.info("清除redis时出现错误！！！");

        }
//        redisTemplate.opsForList().rightPushAll("captureName", allCaptureNames);
        Boolean keyExists = redisTemplate.hasKey("captureName");

        if (Boolean.TRUE.equals(keyExists)) {
            // 如果key存在，直接插入数据
            redisTemplate.opsForList().trim("captureName", 0, 0);  // 清空列表
            log.info("captureName存在，直接插入数据");
            redisTemplate.opsForList().rightPushAll("captureName", allCaptureNames);
        } else {
            //因为大华摄像头正在维护，所有的计划全部停用，所以没有数据，等待大华反馈
            log.info("captureName不存在，创建captureName再插入数据");
//            redisTemplate.opsForList().rightPushAll("captureName", Collections.emptyList());
            redisTemplate.opsForList().rightPushAll("captureName", allCaptureNames);
        }
    }

    //获取当前时间戳
    private static long getTimestampAtTime(int hour, int minute) {
        LocalDate today = LocalDate.now();
        LocalDateTime localDateTime = LocalDateTime.of(today, LocalTime.of(hour, minute))
                .withSecond(0)
                .withNano(0);

        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
        Instant instant = zonedDateTime.toInstant();
        return instant.getEpochSecond(); // 返回以秒为单位的时间戳
    }

    //将时间戳根据系统时区转换为正确的时间
    public static String convertTimestampToZone(long timestamp, String zoneId, String format) {
        Instant instant = Instant.ofEpochSecond(timestamp);
        ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of(zoneId));
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
        return zonedDateTime.format(formatter);
    }

    //把时间戳转换为日期
    public static String extractDate(String dateTimeStr) {
        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        LocalDate date = LocalDate.parse(dateTimeStr, inputFormatter);

        return date.format(outputFormatter);
    }

}
